#include <QCoreApplication> //关于内存管理（什么时候要显示delete）、QObject类和信号槽等的举例
#include "Test1.h"
#include "Test2.h"
#include "Test3.h"
#include "Test4.h"

int main(int argc, char *argv[])
{
//    QCoreApplication a(argc, argv);  //a是对象，是操作系统管的，我们人只要管指针的释放！
// QCoreApplication是Qt核心库里的一个类
//    auto p = new Test1(&a);   //若果不显示加delete p; 系统仍然会调用析构函数~Test1
//a在是个局部变量，在主函数运行完后就会被释放掉（a是Test1的父指针），这种情况不用显示加delete p！
    auto p = new Test1();      //给一个空指针
    auto q = new Test2(0, p);
    auto r = new Test3(10, q);     //因为Test3是继承了Test2，所以自己释放完后还会释放其父类Test2。
    auto u = new Test4(100, r);    //增加了变量100，对应前面的int x

    QObject::connect(p,
                     &Test1::sig_Test1,
                     q,
                     &Test2::slot_test2); //绑定信号槽

    emit p->sig_Test1(8);   // 用sig_Test1触发信号
// 如果想发出信号，务必要用emit显式调用；emit本身也不是原生C++的语法，也是需要运行qmake，将Qt语法转化为原生C++语法。

    delete p;  //C++最麻烦的就是什么时候需要delete，而Qt就是要解决这些问题。
               //就是说，只要把父级指定清楚，在父级释放的时候子级也会跟着释放。
               //Qt的内存管理机制是尽量避免delete的使用！
    //运行到delete p时，Test1类对象p被释放，进而由于q挂在了p的QObject（对象树）上，p是q的对象树的父级，所以，p释放时，会级联释放q，
    //更进一步r也挂在了p的释放树上，p释放时，也会连带释放r，r作为Test3，继承自Test2，所以释放时也会调用父类Test2的析构函数。
    return 0;  //直接返回这个函数
}
